package trend;

/** class global
 * @Author Hussein Patwa
 * @Date 10 March 2007
 * This class implements the global trending algorithm, Fig. 6 on KDD paper.
 */

import java.util.*;
import java.lang.Double;

@SuppressWarnings("all")
public class Global {

    HashSet paths;
    ArrayList path; // ArrayList to hold spatial objects

    int minLength; // length above which path is considered established
    int maxLength; // length above which path is assumed
    int min_conf; // min_conf as noted in pseudo code

    class observation { // define what an observation is
	double dist; // distance from X co-ordinate
	double diff; // distance from Y co-ordinate

	observation(double dist, double diff) {
	    this.dist = dist;
	    this.diff = diff;
}
    }

    public Global(NeighbourhoodInfo neighbourInfo,ArrayList data,int index,int minLength, int maxLength, double min_conf){
	paths = computeAllPaths(neighbourInfo,index,minLength);
        // System.out.println("Number of Paths: "+paths.size());
        findTrends(index,data);
    }
    
    HashSet computeAllPaths(NeighbourhoodInfo neighbourInfo, int index,int minLength){
        // compute all the paths from the spatial object
        // specified by the index using the neighbourhood information
        HashSet rtn = new HashSet();
        Vector tempNeighbours = neighbourInfo.getNeighbourhoodAreaIDs(index);
        // System.out.println("index: "+index+" neighbours : "+tempNeighbours);
        for(Iterator i = tempNeighbours.iterator();i.hasNext();){
            Integer node = (Integer)i.next();
            ArrayList tempPath = new ArrayList();
            tempPath.add(new Integer(index));
            tempPath.add(new Integer(node));
            rtn.add(tempPath);
            // System.out.println(tempPath);
        }
        for(int j=0;j<minLength;j++)
                rtn.addAll(extendPath(rtn,neighbourInfo));
        return rtn;
    }
    
    HashSet extendPath(HashSet paths, NeighbourhoodInfo neighbourInfo){
        HashSet rtn = new HashSet();
        for(Iterator k = paths.iterator();k.hasNext();){
            ArrayList path = (ArrayList)k.next();
            int index = ((Integer)path.get(path.size()-1)).intValue();
            Vector tempNeighbours = neighbourInfo.getNeighbourhoodAreaIDs(index);
            // System.out.println("index: "+index+" neighbours :
	    // "+tempNeighbours);
            for(Iterator i = tempNeighbours.iterator();i.hasNext();){
                Integer node = (Integer)i.next();
                if(!path.contains(node)){
                    ArrayList tempPath = new ArrayList();
                    tempPath.addAll(path);
                    tempPath.add(node);
                    rtn.add(tempPath);
                    // System.out.println(tempPath);
                }
                // tempPath.remove(note);
                // rtn.remove(tempPath);
            }
        }
        return rtn;
    }
    
    // 
    public void findTrends(int index,ArrayList data){
        for(Iterator i = paths.iterator();i.hasNext();){
            path = (ArrayList)i.next(); // Move first element of paths to path
            TreeMap PathObs = new TreeMap();
            for(int j=minLength; j<path.size(); j++) // initialise counter
							// that will track
							// through the colums of
							// the set paths
            {
        	// System.out.println(path.size());
                Integer currentIndex = (Integer)path.get(j);
                Spatialobject o = (Spatialobject)data.get(index);
                Spatialobject object = (Spatialobject)data.get(currentIndex);
                double dist = Math.sqrt(Math.pow((object.getX()-o.getX()),2)+Math.pow((object.getY()-o.getY()),2)); // calculate
														    // the
														    // difference
														    // in
														    // the
														    // x
														    // co-ordinate
                double diff = object.getV()-o.getV(); // calculate the
							// difference in the y
							// co-ordinate
                // observation obsTemp = new observation(dist,diff); // insert
		// distX into observations
                PathObs.put(dist,diff);// insert distY into observations
            }
                Regression reg = new Regression(PathObs);
                TreeMap predObs = reg.getRegressionPredictions();
                // System.out.println(PathObs+" "+predObs);
                
                
                paths.remove(0); // Remove the first position to shift
				    // everything back a place
            }
    
}
    
    
   

// Method to show pos or neg trend set
    public void viewTrends() {
//        for(ArrayList<Integer> p:posTrend){
//            print area names from each path
//            for(Integer index:p){
//                Spatialobject o = (Spatialobject)DATA.get(index);
//                System.out.print(o.getName()+" ");
//            }
//            System.out.println();
//        }
//        for(ArrayList<Integer> n:negTrend){
//            print area names from each path
//            for(Integer index:n){
//                Spatialobject o = (Spatialobject)DATA.get(index);
//                System.out.print(o.getName()+" ");
//            }
//            System.out.println();
//        }
    }


}
